package com.open.source.ams.metadata;

import com.open.source.ams.annotation.ExcelEntity;
import com.open.source.ams.annotation.ExcelEntityProperty;
import com.open.source.ams.model.AbsImportExcelModel;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotEmpty;
import lombok.NoArgsConstructor;
import lombok.var;
import org.apache.commons.lang3.StringUtils;

/**
 * 不支持内部类
 *
 * @author ZonLen since on 2022/3/10 下午2:29
 */
@NoArgsConstructor
public class ImportModelMetadata {

  @NotBlank(message = "元数据全类名不能为空")
  private String className;

  private Integer sheetIndex = 0;

  private Integer startRowIndex;

  @Valid
  @NotEmpty(message = "元数据属性不能为空")
  private final List<ImportPropertyMetadata> importPropertyMetadataList = new ArrayList<>();

  public ImportModelMetadata(String generateClassName, Class<?> importModelClass) {
    this.className = generateClassName;
    final ExcelEntity excelEntity = importModelClass.getAnnotation(ExcelEntity.class);
    if (null == excelEntity) {
      throw new RuntimeException("不是Excel导入模型请检查");
    }
    this.startRowIndex = excelEntity.startRowIdx() <= 0 ? 2 : excelEntity.startRowIdx();
    for (Field declaredField : importModelClass.getDeclaredFields()) {
      final ImportPropertyMetadata importPropertyMetadata = new ImportPropertyMetadata(
          declaredField);
      if (importPropertyMetadata.isImportProperty()) {
        importPropertyMetadataList.add(importPropertyMetadata);
      }
    }
  }

  public Integer getStartRowIndex() {
    return startRowIndex;
  }

  public Integer getSheetIndex() {
    return sheetIndex;
  }

  public List<ImportPropertyMetadata> getImportPropertyMetadataList() {
    return importPropertyMetadataList;
  }

  public String getClassName() {
    if (className.contains("com.yonyou.einvoice")) {
      return className;
    }
    return "com.yonyou.einvoice.generate.imports.model." + simpleClassName();
  }

  public String packageName() {
    if (className.contains("com.yonyou.einvoice")) {
      return className.substring(0, className.lastIndexOf("."));
    }
    return "com.yonyou.einvoice.generate.imports.model";
  }

  public String simpleClassName() {
    return className.substring(className.lastIndexOf(".") + 1);
  }

  public String classPath() {
    return className.substring(0, className.lastIndexOf(".")).replaceAll("\\.", "/");
  }

  public String classCode() {
    var stringBuilder = new StringBuilder();

    if (StringUtils.isNotBlank(packageName())) {
      stringBuilder.append("package  ").append(packageName()).append(";\n");
    }
    stringBuilder.append("@").append(ExcelEntity.class.getName()).append("(startRowIdx = ")
        .append(startRowIndex).append(")\n");
    stringBuilder.append("public class ").append(simpleClassName())
        .append(" extends ").append(AbsImportExcelModel.class.getName()).append(" {\n\n");
    for (ImportPropertyMetadata importPropertyMetadata : this.importPropertyMetadataList) {
      //属性javax校验注解
      for (ValidationPropertyAnnotationMetadata validationPropertyAnnotationMetadata : importPropertyMetadata
          .getValidationPropertyAnnotationMetadataList()) {
        stringBuilder.append("@")
            .append(validationPropertyAnnotationMetadata.getValidateAnnotationType())
            .append("(message = \"")
            .append(validationPropertyAnnotationMetadata.getValidateAnnotationMessage())
            .append("\")\n");
      }
      //属性
      stringBuilder
          .append("@").append(ExcelEntityProperty.class.getName()).append("(index = ")
          .append(importPropertyMetadata.getColumnIndex()).append(")")
          .append("private ").append(importPropertyMetadata.getPropertyType())
          .append(" ").append(importPropertyMetadata.getPropertyName()).append(";\n");
      //get
      stringBuilder.append("public ").append(importPropertyMetadata.getPropertyType())
          .append(" get").append(upCase(importPropertyMetadata.getPropertyName()))
          .append("(){\n")
          .append("return ").append(importPropertyMetadata.getPropertyName())
          .append(";\n}\n\n");
      //set
      stringBuilder.append("public void set")
          .append(upCase(importPropertyMetadata.getPropertyName())).append("(")
          .append(importPropertyMetadata.getPropertyType()).append(" ")
          .append(importPropertyMetadata.getPropertyName())
          .append(") {\n")
          .append("this.").append(importPropertyMetadata.getPropertyName()).append("=")
          .append(importPropertyMetadata.getPropertyName()).append(";\n}\n");
    }
    stringBuilder.append("}");
    return stringBuilder.toString();
  }

  private static String upCase(String val) {
    return val.substring(0, 1).toUpperCase() + val.substring(1);
  }
}
